#include "stdio.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "string.h"

#include "usart.h"
#include "time.h"
#include "iic.h"

#include "bmp.h"
#include "oled.h"
#include "oled_windows.h"

#include "key.h"
#include "matrix_key.h"

#include "fan.h"
#include "wifi.h"
#include "at24cxx.h"
#include "beep.h"
#include "as608.h"

//#include "rc522_config.h"
//#include "rc522_function.h"
//#include "led.h"
//#include "adc.h"
//#include "dht11.h"


#define PASSWORD_ADDR 0X40	//密码存储初始地址--AT24Cxx，共24个字节，前12字节为管理员用户，后12字节为普通用户
//-----------------------------通讯协议----------------------------------
//传感器数据
typedef struct SensorData
{
    char  sensor_name[15];
    char  sensor_value;
}SensorData;

//设备状态
typedef struct DeviceData
{
    char  device_name[15];
    char  device_status;	//1 on,0 off
    char  device_level;
}DeviceData;

//上传数据
typedef struct UpData
{
    int room_num;
    SensorData sensor_data[6];
    DeviceData device_data[6];
}UpData;

//下发数据
typedef struct DownData
{
    int room_num;
    DeviceData device_data;
}DownData;

//数据包
 typedef struct Message
 {
     char message_type;		//0--传感器数据和设备状态、1--控制指令
     char message_content[400];	//	memcpy(message_content,up_data | down_data,sizeof(up_data | down_data))
     int sum_check;	//strlen(message_content)//和校验
 }Message;
//------------------------------------------------------------------------------------
extern u16 ID;
//转发消息数据和标志
Message message;
char message_flag=0;

//设备和传感器数据
char led_status;
char fan_status;
char fan_level;
char temperature;
char humidity;
char light;


//OLED屏幕当前所在行数
char oled_line = 1;
char window_num = 0;

//按键1-3是被点击
char key1_status;
char key2_status;
char key3_status;

//队列句柄
QueueHandle_t key_value_handle;
QueueHandle_t input_password_handle;
QueueHandle_t clean_input_handle;

//FreeRTOS任务句柄
TaskHandle_t matrix_key_handle;	//矩形键盘任务句柄
TaskHandle_t oled_handle;	//OLED屏任务句柄
TaskHandle_t forWard_data_handle;	//数据转发任务句柄
TaskHandle_t finger_printTask_handle;//指纹识别任务句柄


//----门锁+显示屏任务	
void displayOledTask(void *pvParameters)
{
	u16 addr,input_ID;
	char i,j,k,key_value;
	char input_password[12],password[2][12];

	addr = PASSWORD_ADDR;
	taskENTER_CRITICAL();
	for(i=0;i < 2;i++)
	{
		for(j=0;j < 12;j++)
		{
			password[i][j] = at24cxxRdata(addr++);
		}
	}
	taskEXIT_CRITICAL();
	addr = PASSWORD_ADDR;
	
	while(1)	
	{
		switch (window_num)
		{
			case 0://--欢迎界面
				oled_window0();
				while(window_num == 0)
				{
					if(xQueueReceive(key_value_handle,&key_value,10) == pdTRUE)
					{
						if(key_value == '#')
						{
							window_num = 1;
							
						}
							
						else if(key_value == '*')
						{
							window_num = 2;
						}
						xQueueSend(clean_input_handle,&k,10);
					}
				}
				break;
				
			case 1://--验证密码界面
				oled_window1();	
				while(window_num == 1)
				{
					if(xQueueReceive(input_password_handle,input_password,10) == pdTRUE)
					{
						for(i = 0;i < 8; i++)
						{
							OLED_ShowChar(30+8*i,34,0,12,1);//清空
						}
						for(i = 0;i < strlen(input_password); i++)
						{
							OLED_ShowChar(30+8*i,34,42,12,1);//*
						}
						OLED_Refresh();	
					}
					if(xQueueReceive(key_value_handle,&key_value,10) == pdTRUE)
					{
						if(key_value == '#')
						{
							if(strcmp(input_password,password[0]) == 0 || strcmp(input_password,password[1]) == 0)
							{
								beepOpen();
								vTaskDelay(500);
								beepClose();
								window_num = 0;
							}
							else
							{
								oled_window20();
								vTaskDelay(2000);
								window_num = 0;
							}
							xQueueSend(clean_input_handle,&k,10);
						}
					}
				}
				break;
				
			case 2://准备进入管理员界面--验证管理员密码
				oled_window2();
				while(window_num == 2)
				{
					if(xQueueReceive(input_password_handle,input_password,10) == pdTRUE)
					{
						for(i = 0;i < 8; i++)
						{
							OLED_ShowChar(30+8*i,34,0,12,1);//清空
						}
						for(i = 0;i < strlen(input_password); i++)
						{
							OLED_ShowChar(30+8*i,34,42,12,1);//*
						}
						OLED_Refresh();	
					}
					
					if(xQueueReceive(key_value_handle,&key_value,10) == pdTRUE)
					{
						if(key_value == '#')
						{
							if(strcmp(input_password,password[0]) == 0)
							{
								window_num = 3;
							}
							else
							{
								oled_window20();
								vTaskDelay(2000);
								window_num = 0;
							}
							xQueueSend(clean_input_handle,&k,10);
						}
					}
				}
				break;

			case 3://管理员界面--功能选择
				oled_window3_1();
				while(window_num == 3)
				{
					if(xQueueReceive(key_value_handle,&key_value,10) == pdTRUE)
					{
						if(key_value == '*')
						{
							switch(oled_line)
							{
								case 1:
									oled_window3_2();
									break;
								case 2:
									oled_window3_3();
									break;
								case 3:
									oled_window3_4();
									break;
								case 4:
									oled_window3_1();
									break;
							}
						}
						else if(key_value == '#')
						{
							switch(oled_line)
							{
								case 1:
									window_num = 4;
									break;
								case 2:
									window_num = 5;
									break;
								case 3:
									window_num = 7;
									break;
								case 4:
									window_num = 0;
									break;
							}
							xQueueSend(clean_input_handle,&k,10);
						}	
					}
				}
				break;
				
			case 4://--修改密码--输入新密码
				oled_window4();
				while(window_num == 4)
				{
					if(xQueueReceive(input_password_handle,input_password,10) == pdTRUE)
					{
						for(i = 0;i < 8; i++)
						{
							OLED_ShowChar(42+8*i,34,0,12,1);//清空
						}
						for(i = 0;i < strlen(input_password); i++)
						{
							OLED_ShowChar(42+8*i,34,42,12,1);//*
						}
						OLED_Refresh();	
					}

					if(xQueueReceive(key_value_handle,&key_value,10) == pdTRUE)
					{
						if(key_value == '#')
						{
							strcpy(password[1],input_password);
							oled_window21();
							vTaskDelay(2000);
							window_num = 3;
							xQueueSend(clean_input_handle,&k,10);
							
							//如果密码做了修改，及时保存到AT24Cxx芯片中
							
							for(i=0;i<2;i++)
							{
								for(j=0;j<12;j++)
								{	
									taskENTER_CRITICAL();
									at24cxxWdata(addr++,password[i][j]);
									taskEXIT_CRITICAL();
								}
							}
							addr = PASSWORD_ADDR;
							
						}
					}
				}
				break;
				
			case 5://--指纹录入--输入指纹ID
				oled_window5();
				while(window_num == 5)
				{

					if(xQueueReceive(input_password_handle,input_password,10) == pdTRUE)
					{
						for(i = 0;i < 3; i++)
						{
							OLED_ShowChar(48+6*k,34,0,12,1);//清空
						}
						for(i = 0;i < strlen(input_password); i++)
						{
							if(i < 4)
							{
								OLED_ShowChar(48+6*k,34,input_password[i],12,1);//*
							}
						}
						OLED_Refresh();	
					}


					if(xQueueReceive(key_value_handle,&key_value,10) == pdTRUE)
					{
						if(key_value == '#')
						{
							input_ID = atoi(input_password);
							if(input_ID < 300 && input_ID >=0)
							{
								window_num = 6;
								ID = input_ID;
							}
							else
							{
								window_num = 3;	
							}
							xQueueSend(clean_input_handle,&k,10);
						}
					}
				}
				break;

			case 6://--指纹录入--指纹识别中
				oled_window6();
				while(window_num == 6)
				{
					if(Add_FR())
					{
						oled_window22();
						vTaskDelay(2000);
						window_num = 3;
					}
					else 
					{
						oled_window24();
						vTaskDelay(2000);
						window_num = 3;
					}
					xQueueSend(clean_input_handle,&k,10);
				}
				break;

			case 7://--指纹删除--输入指纹ID
				oled_window7();
				while(window_num == 7)
				{
					if(xQueueReceive(input_password_handle,input_password,10) == pdTRUE)
					{
						for(i = 0;i < 3; i++)
						{
							OLED_ShowChar(48+6*k,34,0,12,1);//清空
						}
						for(i = 0;i < strlen(input_password); i++)
						{
							if(i < 4)
							{
								OLED_ShowChar(48+6*k,34,input_password[i],12,1);//*
							}
						}
						OLED_Refresh();	
					}

					if(xQueueReceive(key_value_handle,&key_value,10) == pdTRUE)
					{
						if(key_value == '#')
						{
							ID = atoi(input_password);
							if(Del_FR())
							{
								oled_window23();
								vTaskDelay(2000);
								window_num = 3;
							}
							else
							{
								oled_window25();
								vTaskDelay(2000);
								window_num = 3;
							}
							xQueueSend(clean_input_handle,&k,10);
						}
					}
				}
				break;

		}
	}
}

//----矩形键盘任务		'#'--确认输入		  '*'返回
void matrixKeyTask(void *pvParameters)
{

	char i,key_value,input_password_index;
	char input_password[12];

	while(1)
	{
		//矩阵键盘扫描
//		key_value = matrixKeyScan();
		if(key_value)	
		{	
			xQueueSend(key_value_handle,&key_value,10);	
			//如果其他值则保存输入值置于输入密码数组中
			if((key_value >= '0' && key_value <= '9') && strlen(input_password) < 8)
			{
				input_password[input_password_index++] = key_value;
				xQueueSend(input_password_handle,input_password,10);
			}
			else if(key_value == '*' && input_password_index > 0)
			{
				input_password[--input_password_index] = 0;
				xQueueSend(input_password_handle,input_password,10);
			}
		}
		if(xQueueReceive(clean_input_handle,&i,10) == pdTRUE)
		{
			memset(input_password,0,sizeof(input_password));
			xQueueReset(input_password_handle);
			input_password_index = 0;
			key_value = 0;
		}
	}
}

//----数据转发任务
void forWardDataTask(void *pvParameters)
{
	char i;
	char AT_commend[128];	
	wifiInit();//wifi初始化	
	while(1)
	{
		if(message_flag == 1)
		{
			message_flag = 0;
			if(message.message_type  == 0)	//上传数据
			{
				printf("22222222222222222222222222222222222222\k");
				sprintf(AT_commend,"AT+CIPSEND=%d,%d\r\k",0,sizeof(message));
				taskENTER_CRITICAL();
				usartSendStr(USART2,AT_commend,sizeof(AT_commend));
				taskEXIT_CRITICAL();
				
				vTaskDelay(200);
				taskENTER_CRITICAL();
				usartSendStr(USART2,(char*)&message,sizeof(message));
				taskEXIT_CRITICAL();	
			}
			
			else if(message.message_type  == 1)	//下发数据
			{
				printf("33333333333333333333333333333333333333333333\k");
				sprintf(AT_commend,"AT+CIPSEND=%d,%d\r\k",i,sizeof(message));
				for(i=0;i<5;i++)
				{
					taskENTER_CRITICAL();
					usartSendStr(USART2,AT_commend,sizeof(AT_commend));
					taskEXIT_CRITICAL();
					
					vTaskDelay(200);
					taskENTER_CRITICAL();
					usartSendStr(USART2,(char*)&message,sizeof(message));
					taskEXIT_CRITICAL();
				}
			}
		}
	}		
}

//指纹识别任务
void fingerPrintTask(void *pvParameters)
{
	AS608_init();	//指纹模块初始化
	while(1)
	{
		if(press_FR())	//指纹识别成功
		{
			beepOpen();
			vTaskDelay(500);
			beepClose();
		}
	}				
}
//主程序入口
int main(){
	//中断优先级分组
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);	
	
	usart1Init();//usart1初始化，用于输出调试信息
	usart2Init();//usart2初始化，用于与ESP12S连接实现无线通信
	usart3Init();//与指纹进行通信
	
	PS_StaGPIO_Init();//PE3口初始化
	
	tim2Init();//--用作指纹模块定时器
	tim3Init();//基本定时器3初始化--延时定时器
	tim4Init();//通用定时器4初始化--舵机PWM控制
	beepInit();//蜂鸣器初始化

	OLED_Init();	//OLED屏幕初始化
	matrixKeyInit();	//矩形按键初始化

	//创建队列长度为5的消息队列
	key_value_handle = xQueueCreate(1, sizeof(char));
	input_password_handle = xQueueCreate(1, sizeof(char)*12);
	clean_input_handle = xQueueCreate(1, sizeof(char));
	
	xTaskCreate(displayOledTask,"displayOledTask",128,NULL,2,oled_handle);
	xTaskCreate(matrixKeyTask,"matrixKeyTask",128,NULL,2,matrix_key_handle);
	xTaskCreate(forWardDataTask,"forWardDataTask",256,NULL,2,forWard_data_handle);
	xTaskCreate(fingerPrintTask,"fingerPrintTask",256,NULL,2,finger_printTask_handle);
	vTaskStartScheduler();
	
}





//	tim6Init();//基本定时器6初始化--按键复用判断定时器	
//	//按键1，2，3，4初始化
//	keyInit(GPIO_Pin_4);
//	keyInit(GPIO_Pin_5);
//	keyInit(GPIO_Pin_6);
//	key4Init();
//	extiInit();//按键外部中断初始化

//u8 ucStatusReturn;    //返回RFID状态
//u8 ucArray_ID [ 4 ];	 //先后存放IC卡的类型和UID(IC卡序列号)		

////RFID射频识别
//void rc522Task(void *pvParameters)
//{
//	while(1)
//	{
//		//RC522读取IC卡，进入范围则蜂鸣器提示
//		taskENTER_CRITICAL();
//		ucStatusReturn = PcdRequest(PICC_REQALL, ucArray_ID);
//		taskEXIT_CRITICAL();
//		if(ucStatusReturn == MI_OK  )
//		{
//			beepOpen();
//			vTaskDelay(300);
//			beepClose();
//		}
//		vTaskDelay(300);
//	}
//}

//	RC522_Init ();	//RFID-RC522射频识别初始化
//	PcdReset ();	//RFID-RC522复位
//	M500PcdConfigISOType ( 'A' );//设置RFID-RC522工作方
//	xTaskCreate(rc522Task,"rc522Task",128,NULL,2,rc522_handle);

//	//设备初始化
//	ledInit(GPIO_Pin_8);
//	ledInit(GPIO_Pin_9);
//	ledInit(GPIO_Pin_10);
//	fanInit();//风扇由N型MOS管控制，需要在N端提供高电平导通
//	//传感器初始化
//	adcInit();		//adc初始化，用于获取光照传感器数据
//	dht11Init();	//dht11温湿度传感器初始化



